Typical HAL DCACHE use cases for migration

This section provides information about the applicable HAL DCACHE use cases for migration.

Use case: DCACHE maintenance operations in polling mode

Sequence diagram

DCACHE maintenance operations in polling mode.

  @startuml
  skinparam sequenceMessageAlign center

  participant "User\nApplication" as UA
  participant "DCACHE\nDriver" as DD

  UA->DD : **HAL_DCACHE_Init**
  DD-->"Driver RCC" : Compilation switch: clock activation
  rnote over DD
  Invalidate Operation by Hardware
  endrnote
  UA <-- DD : return HAL_OK or HAL_INVALID_PARAM
  |||
  group Loop [Can be repeated]

  group Optional
  UA->DD : **HAL_DCACHE_SetReadBurstType**
  DD --> UA : return HAL_OK

  UA->DD : **HAL_DCACHE_Monitor_Start**
  DD --> UA : return HAL_OK
  |||
  end

  UA->DD : **HAL_DCACHE_Enable**
  DD --> UA : return HAL_OK

  group Loop [Can be repeated]

  UA->DD : **HAL_DCACHE_Invalidate**,\n**...**\n**HAL_DCACHE_CleanByAddr**,\n**...**\n**HAL_DCACHE_InvalidateByAddr**,\n**...**\n**HAL_DCACHE_CleanInvalidByAddr**,\n**...**
  DD --> UA : return HAL_OK, HAL_BUSY, HAL_ERROR
  |||
  end

  group Optional
  UA->DD : **HAL_DCACHE_Monitor_GetReadHitValue**, **HAL_DCACHE_Monitor_GetReadMissValue**,\n**HAL_DCACHE_Monitor_GetWriteHitValue**, **HAL_DCACHE_Monitor_GetWriteMissValue**
  DD --> UA : Monitor's value

  UA->DD : **HAL_DCACHE_Monitor_Reset**
  DD --> UA : return HAL_OK

  end
  |||
  UA->DD : **HAL_DCACHE_Disable**
  DD --> UA : return HAL_OK
  |||
  end
  |||
  UA->DD : **HAL_DCACHE_DeInit**
  DD --> UA

  @enduml

Code snippet

HAL1

HAL2

/* Init */
HAL_DCACHE_Init(&hdcache);

/* Optional configuration */
HAL_DCACHE_SetReadBurstType(&hdcache, HAL_DCACHE_READ_BURST_WRAP);
HAL_DCACHE_Monitor_Start(&hdcache);

/* Enable DCACHE */
HAL_DCACHE_Enable(&hdcache);

/* Maintenance operations (repeat as needed) */
HAL_DCACHE_Invalidate(&hdcache);
HAL_DCACHE_CleanByAddr(&hdcache, (uint32_t *)buffer, buffer_size);
HAL_DCACHE_InvalidateByAddr(&hdcache, (uint32_t *)buffer, buffer_size);
HAL_DCACHE_CleanInvalidByAddr(&hdcache, (uint32_t *)buffer, buffer_size);

/* Optional monitoring */
(void)HAL_DCACHE_Monitor_GetReadHitValue(&hdcache);
(void)HAL_DCACHE_Monitor_GetReadMissValue(&hdcache);
(void)HAL_DCACHE_Monitor_GetWriteHitValue(&hdcache);
(void)HAL_DCACHE_Monitor_GetWriteMissValue(&hdcache);
HAL_DCACHE_Monitor_Reset(&hdcache);

/* Stop DCACHE */
HAL_DCACHE_Disable(&hdcache);
HAL_DCACHE_DeInit(&hdcache);
/* Init */
HAL_DCACHE_Init(&hdcache);

/* Optional configuration */
HAL_DCACHE_SetReadBurstType(&hdcache, HAL_DCACHE_READ_BURST_WRAP);
HAL_DCACHE_ECC_Enable(&hdcache);
HAL_DCACHE_EnableMonitors(&hdcache);

/* Start DCACHE (no interrupt) */
HAL_DCACHE_Start(&hdcache, HAL_DCACHE_IT_NONE);

/* Maintenance operations (repeat as needed) */
HAL_DCACHE_Invalidate(&hdcache);
HAL_DCACHE_CleanByAddr(&hdcache, (uint32_t *)buffer, buffer_size);
HAL_DCACHE_InvalidateByAddr(&hdcache, (uint32_t *)buffer, buffer_size);
HAL_DCACHE_CleanInvalidByAddr(&hdcache, (uint32_t *)buffer, buffer_size);

/* Optional monitoring */
(void)HAL_DCACHE_GetMonitorReadHitValue(&hdcache);
(void)HAL_DCACHE_GetMonitorReadMissValue(&hdcache);
(void)HAL_DCACHE_GetMonitorWriteHitValue(&hdcache);
(void)HAL_DCACHE_GetMonitorWriteMissValue(&hdcache);
HAL_DCACHE_ResetMonitors(&hdcache);
HAL_DCACHE_ECC_Disable(&hdcache);

/* Stop DCACHE */
HAL_DCACHE_Stop(&hdcache);
HAL_DCACHE_DeInit(&hdcache);

Key changes

  1. HAL2 uses HAL_DCACHE_Start() / HAL_DCACHE_Stop() instead of HAL_DCACHE_Enable() / HAL_DCACHE_Disable().

  2. HAL2 adds optional ECC control and monitor configuration APIs.

  3. HAL2 monitor getter and reset APIs are renamed compared to HAL1.


Use case: DCACHE maintenance operations in interrupt mode

Sequence diagram

DCACHE maintenance operations in interrupt mode.

  @startuml
  participant "User\nApplication" as UA
  participant "DCACHE\nDriver" as DD
  participant "DCACHE_IRQHandler" as IRQ

  skinparam sequenceMessageAlign center

  == DCACHE Initialization ==
  |||
  opt
      UA ->  DD : **HAL_DCACHE_RegisterCallback**(&hdcache, HAL_DCACHE_CLEAN_BY_ADDRESS_CB_ID, USER_DCACHE_InvalidateCompleteCallback)\n**HAL_DCACHE_RegisterCallback**(&hdcache, HAL_DCACHE_CLEAN_BY_ADDRESS_CB_ID, USER_DCACHE_CleanByAddrCallback)\n**HAL_DCACHE_RegisterCallback**(&hdcache, HAL_DCACHE_INVALIDATE_BY_ADDRESS_CB_ID, USER_DCACHE_InvalidateByAddrCallback)\n**HAL_DCACHE_RegisterCallback**(&hdcache, HAL_DCACHE_CLEAN_AND_INVALIDATE_BY_ADDRESS_CB_ID, USER_DCACHE_CleanAndInvalidateByAddrCallback)
      DD --> UA : return HAL_OK
  end
  |||
  UA->DD : **HAL_DCACHE_Enable**
  DD --> UA : return HAL_OK
  UA -> DD : **__HAL_DCACHE_ENABLE_IT**
  note right : Choose to enable Eviction Clean error interrupt
  |||
  UA -> DD : **HAL_DCACHE_CleanByAddr_IT**,\n**...**\n**HAL_DCACHE_InvalidateByAddr_IT**,\n**...**\n**HAL_DCACHE_CleanInvalidByAddr_IT**,\n**...**\n**HAL_DCACHE_Invalidate_IT**,\n**...**
  rnote over DD
  Flag Command Interrupt (CMDENDIE) enabled or
      Flag Invalidate Interrupt (BSYENDIE) enabled
  endrnote
  DD --> UA : return HAL_OK or HAL_ERROR
  |||
  == Interruption Service Routine ==
  |||
  IRQ <- : DCACHE Maintenance interrupt
  IRQ -> DD : **HAL_DCACHE_IRQHandler**
  note left : Interruption execution\nDisable BSYEND or CMDEND interrupt
  alt USE_HAL_DCACHE_REGISTER_CALLBACKS
      DD -> UA : **USER_DCACHE_InvalidateCompleteCallback**\n**USER_DCACHE_CleanByAddrCallback**\n**USER_DCACHE_InvalidateByAddrCallback**\n**USER_DCACHE_CleanAndInvalidateByAddrCallback**
      DD <-- UA
  else USE OVERRIDDEN WEAK CALLBACKS
      DD -> UA : **HAL_DCACHE_InvalidateCompleteCallback**\n**HAL_DCACHE_CleanByAddrCallback**\n**HAL_DCACHE_InvalidateByAddrCallback**\n**HAL_DCACHE_CleanAndInvalidateByAddrCallback**
      DD <-- UA
  end
  |||
  @enduml

Code snippet

HAL1

HAL2

/* Optional: register callbacks */
HAL_DCACHE_RegisterCallback(&hdcache, HAL_DCACHE_CLEAN_BY_ADDRESS_CB_ID,
                            USER_DCACHE_CleanByAddrCallback);
HAL_DCACHE_RegisterCallback(&hdcache, HAL_DCACHE_INVALIDATE_BY_ADDRESS_CB_ID,
                            USER_DCACHE_InvalidateByAddrCallback);

HAL_DCACHE_Enable(&hdcache);
__HAL_DCACHE_ENABLE_IT(&hdcache, DCACHE_IT_CMDEND | DCACHE_IT_BSYEND | DCACHE_IT_ERR);

/* Trigger maintenance operations in interrupt mode */
HAL_DCACHE_CleanByAddr_IT(&hdcache, (uint32_t *)buffer, buffer_size);

/* In IRQ handler */
void DCACHE_IRQHandler(void)
{
  HAL_DCACHE_IRQHandler(&hdcache);
}
/* Optional: register callbacks */
HAL_DCACHE_RegisterCleanByAddrCallback(myDCACHE_CleanByAddrCallback);
HAL_DCACHE_RegisterInvalidateByAddrCallback(myDCACHE_InvalidateByAddrCallback);

/* Start DCACHE with error interrupt enabled */
HAL_DCACHE_Start(&hdcache, HAL_DCACHE_IT_ERROR);

/* Trigger maintenance operations in interrupt mode */
HAL_DCACHE_CleanByAddr_IT(&hdcache, (uint32_t *)buffer, buffer_size);

/* In IRQ handler */
void DCACHE_IRQHandler(void)
{
  HAL_DCACHE_IRQHandler(&hdcache);
}

Key changes

  1. HAL2 provides dedicated callback registration APIs instead of using callback IDs.

  2. HAL2 uses HAL_DCACHE_Start() to enable the peripheral and interrupts.

  3. The IRQ handler entry point remains HAL_DCACHE_IRQHandler().

Use case: DCACHE error interrupt handling

Sequence diagram

DCACHE error interrupt handling.

  @startuml
  participant "User\nApplication" as UA
  participant "DCACHE\nDriver" as DD
  participant "DCACHE_IRQHandler" as IRQ

  skinparam sequenceMessageAlign center

  == Init DCACHE ==
  |||
  opt USE_HAL_DCACHE_REGISTER_CALLBACKS
      UA -> DD: **HAL_DCACHE_RegisterCallback**(&hdcache, HAL_DCACHE_ERROR_CB_ID, USER_DCACHE_ErrorCallback)
      DD --> UA : return HAL_OK
  end
  |||
  UA -> DD : **HAL_DCACHE_Enable**
  DD --> UA : return HAL_OK
  UA -> DD : **__HAL_DCACHE_ENABLE_IT**
  note right : Enable Interruption (Eviction Clean)
  |||
  == Interruption Service Routine ==
  |||
  IRQ <- : Error\ninterrupt
  IRQ -> DD : **HAL_DCACHE_IRQHandler**
  note left : Interruption execution
  alt USE_HAL_DCACHE_REGISTER_CALLBACKS
      DD -> UA : **USER_DCACHE_ErrorCallback**
      DD <-- UA
  else USE OVERRIDDEN WEAK CALLBACKS
      DD -> UA : **HAL_DCACHE_ErrorCallback**
      DD <-- UA
  end
  |||
  @enduml

Code snippet

HAL1

HAL2

/* Optional: register error callback */
HAL_DCACHE_RegisterCallback(&hdcache, HAL_DCACHE_ERROR_CB_ID,
                            USER_DCACHE_ErrorCallback);

HAL_DCACHE_Enable(&hdcache);
__HAL_DCACHE_ENABLE_IT(&hdcache, DCACHE_IT_ERR);

/* In IRQ handler */
void DCACHE_IRQHandler(void)
{
  HAL_DCACHE_IRQHandler(&hdcache);
}
/* Optional: register error callback */
HAL_DCACHE_RegisterErrorCallback(DCACHE_Error_UserCallback);

/* Start DCACHE with error interrupt enabled */
HAL_DCACHE_Start(&hdcache, HAL_DCACHE_IT_ERROR);

/* In IRQ handler */
void DCACHE_IRQHandler(void)
{
  HAL_DCACHE_IRQHandler(&hdcache);
}

Key changes

  1. HAL2 uses HAL_DCACHE_RegisterErrorCallback() instead of registering by callback ID.

  2. HAL2 enables error interrupts as part of HAL_DCACHE_Start().

  3. Error processing is still performed through HAL_DCACHE_IRQHandler().


Use case: DCACHE maintenance in polling mode with error interrupt enabled

Sequence diagram

DCACHE maintenance in polling mode with error interrupt enabled.

  @startuml
  participant "User\nApplication" as UA order 1
  participant "DCACHE\nDriver" as DD order 2
  participant "DCACHE_IRQHandler" as IRQ order 3

  skinparam sequenceMessageAlign center

  == DCACHE Initialization ==

  group Option [USE_HAL_DCACHE_REGISTER_CALLBACKS]
  UA ->  DD : **HAL_DCACHE_RegisterCallback**(&hdcache, HAL_DCACHE_ERROR_CB_ID, USER_DCACHE_ErrorCallback)
  DD --> UA : return HAL_OK
  end
  UA -> DD : **HAL_DCACHE_Enable**
  DD --> UA : return HAL_OK
  UA -> DD : **__HAL_DCACHE_ENABLE_IT**
  rnote over DD
  Enable ERROR Interrupt
  endrnote
  |||
  UA-[#blue]>DD : **HAL_DCACHE_CleanByAddr**
  activate DD #blue
  note over DD : Check Busy flag : Flag = 0
  IRQ <[#orange]- : DCACHE Error interrupt
  IRQ -[#orange]> DD : **HAL_DCACHE_IRQHandler**
  activate DD #orange
  note over DD : Flag Error Interrupt = 1
  alt USE_HAL_DCACHE_REGISTER_CALLBACKS
  DD -[#orange]> UA : **USER_DCACHE_ErrorCallback**
  UA -[#orange]-> DD
  else USE OVERRIDDEN WEAK CALLBACKS
  DD -[#orange]> UA : **HAL_DCACHE_ErrorCallback**
  UA -[#orange]-> DD
  end
  deactivate DD
  DD -[#blue]-> UA : return HAL_OK
  deactivate DD
  |||
  rnote over UA
  The user can call __HAL_DCACHE_DISABLE_IT() to disable the Error Interrupt
  and call HAL_DCACHE_Disable() to stop the DCACHE or make an other action.
  endrnote
  @enduml

Code snippet

HAL1

HAL2

/* Enable error interrupt */
HAL_DCACHE_RegisterCallback(&hdcache, HAL_DCACHE_ERROR_CB_ID,
                            USER_DCACHE_ErrorCallback);
HAL_DCACHE_Enable(&hdcache);
__HAL_DCACHE_ENABLE_IT(&hdcache, DCACHE_IT_ERR);

/* Run a maintenance operation */
(void)HAL_DCACHE_CleanByAddr(&hdcache, (uint32_t *)buffer, buffer_size);

/* In IRQ handler */
void DCACHE_IRQHandler(void)
{
  HAL_DCACHE_IRQHandler(&hdcache);
}
/* Enable error interrupt */
HAL_DCACHE_RegisterErrorCallback(myDCACHE_ErrorCallback);
HAL_DCACHE_Start(&hdcache, HAL_DCACHE_IT_ERROR);

/* Run a maintenance operation */
(void)HAL_DCACHE_CleanByAddr(&hdcache, (uint32_t *)buffer, buffer_size);

/* In IRQ handler */
void DCACHE_IRQHandler(void)
{
  HAL_DCACHE_IRQHandler(&hdcache);
}

Key changes

  1. HAL2 uses HAL_DCACHE_RegisterErrorCallback() instead of registering by callback ID.

  2. HAL2 enables error interrupts via HAL_DCACHE_Start().

  3. The cache maintenance call remains HAL_DCACHE_CleanByAddr().